package org.boulderfoodrescue.webapp.client.managers;

import java.util.LinkedList;
import java.util.List;

import org.boulderfoodrescue.webapp.client.events.ChangeType;
import org.boulderfoodrescue.webapp.client.events.DonorInfoUpdatedEvent;
import org.boulderfoodrescue.webapp.client.events.DonorInfoUpdatedHandler;
import org.boulderfoodrescue.webapp.client.events.RecipientInfoUpdatedEvent;
import org.boulderfoodrescue.webapp.client.events.RecipientInfoUpdatedHandler;
import org.boulderfoodrescue.webapp.client.rpc.LocationServiceAsync;
import org.boulderfoodrescue.webapp.shared.Location;
import org.boulderfoodrescue.webapp.shared.Location.LocationType;

import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class LocationInfoManager {
	private static List<Location> donorList;
	private static List<Location> recipientList;
	private static LocationServiceAsync donorRPC;
	private static EventBus eventBus;
	public LocationInfoManager(LocationServiceAsync donorRPC, EventBus eventBus)
	{
		LocationInfoManager.donorRPC = donorRPC;
		LocationInfoManager.eventBus = eventBus;
		bind();
	}

	private void bind()
	{
		eventBus.addHandler(DonorInfoUpdatedEvent.getType(), 
				new DonorInfoUpdatedHandler(){

			@Override
			public void onDonorAdded(DonorInfoUpdatedEvent event) {
				donorList.add(event.getValue());
			}

			@Override
			public void onDonorRemoved(DonorInfoUpdatedEvent event) {
				donorList.remove(event.getValue());
			}

			@Override
			public void onDonorUpdated(DonorInfoUpdatedEvent event) {
			}

		});

		eventBus.addHandler(RecipientInfoUpdatedEvent.getType(), 
				new RecipientInfoUpdatedHandler(){
			@Override
			public void onRecipientAdded(RecipientInfoUpdatedEvent event) {
				recipientList.add(event.getValue());
			}

			@Override
			public void onRecipientRemoved(RecipientInfoUpdatedEvent event) {
				recipientList.remove(event.getValue());
			}

			@Override
			public void onRecipientUpdated(RecipientInfoUpdatedEvent event) {
			}
		});
	}

	public static List<Location> getDonorList() {
		if(donorList == null){
			donorList = new LinkedList<Location>();
			LoadDonors();
		}
		return donorList;
	}

	private static void LoadDonors()
	{
		donorRPC.getDonors(new AsyncCallback<List<Location>>(){
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Could not load donor list");
			}
			@Override
			public void onSuccess(List<Location> result) {
				if(result == null)
				{
					Window.alert("Error getting donor list. Result is null");
				}
				else{
					for(Location d : result)
					{
						eventBus.fireEvent(new DonorInfoUpdatedEvent(ChangeType.Added, d));
					}
				}
			}
		});
	}

	public static void saveLocationInfo(final Location location){
		final Boolean update;
		if(location.getDatabaseKey() != null && location.getDatabaseKey() != 0){
			update = true;
		}
		else
			update = false;
		donorRPC.saveLocationData(location, new AsyncCallback<Long>(){

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Failed to save location info");
			}

			@Override
			public void onSuccess(Long result) {
				if(result == null)
					Window.alert("Failed to save location info. Result is null.");
				else{
					location.setDatabaseKey(result);
					ChangeType type = update ? ChangeType.Updated : ChangeType.Added;
					if(location.getType() == LocationType.Recipient)
						eventBus.fireEvent(new RecipientInfoUpdatedEvent(type, location));
					else
						eventBus.fireEvent(new DonorInfoUpdatedEvent(type, location));
				}
			}

		});
	}

	public static List<Location> getRecipientList() {
		if(recipientList == null){
			recipientList = new LinkedList<Location>();
			LoadRecipients();
		}
		return recipientList;
	}

	private static void LoadRecipients() {
		donorRPC.getRecipients(new AsyncCallback<List<Location>>(){
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Could not load donor list");
			}
			@Override
			public void onSuccess(List<Location> result) {
				if(result == null)
				{
					Window.alert("Error getting donor list. Result is null");
				}
				else{
					for(Location d : result)
					{
						eventBus.fireEvent(new RecipientInfoUpdatedEvent(ChangeType.Added, d));
					}
				}
			}
		});
	}
}
